#include <QtCore>
#include <QtGui>

#include "SettingDialog.h"
#include "ui_SettingDialog.h"
#include "mixiVoice.h"

SettingDialog::SettingDialog(QSettings *s, QWidget *parent) :
	QDialog(parent),
	m_ui(new Ui::SettingDialog), settings(s)
{
	m_ui->setupUi(this);
	m_ui->textColor->addItems(QColor::colorNames());
	connect(m_ui->textColor, SIGNAL(currentIndexChanged(int)), this, SLOT(applyColors()));
	m_ui->backgroundColor->addItems(QColor::colorNames());
	connect(m_ui->backgroundColor, SIGNAL(currentIndexChanged(int)), this, SLOT(applyColors()));

	m_ui->hiddenUserID->setValidator(new QIntValidator(this));
	connect(m_ui->addHiddenUser, SIGNAL(clicked()), this, SLOT(addHiddenUser()));
	connect(m_ui->deleteHiddenUser, SIGNAL(clicked()), this, SLOT(removeHiddenUser()));

	connect(m_ui->clearImageCache, SIGNAL(clicked()), this, SLOT(clearImageCache()));

	connect(m_ui->chooseSound, SIGNAL(clicked()), this, SLOT(chooseSound()));

	connect(m_ui->startup, SIGNAL(toggled(bool)), this, SLOT(toggleStartupCurrentUser(bool)));

	// Filter
	connect(m_ui->filterList, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(selectFilterItem(QTreeWidgetItem *, QTreeWidgetItem *)));
	connect(m_ui->filterAdd, SIGNAL(clicked()), this, SLOT(addFilter()));
	connect(m_ui->filterChange, SIGNAL(clicked()), this, SLOT(changeFilter()));
	connect(m_ui->filterDel, SIGNAL(clicked()), this, SLOT(deleteFilter()));
	connect(m_ui->filterReset, SIGNAL(clicked()), this, SLOT(resetFilter()));

	if (settings == NULL)	return;

	loadFilters();
	m_ui->enableFilter->setChecked(settings->value(Setting::FilterEnabled, m_ui->enableFilter->isChecked()).toBool());

	m_ui->email->setText(settings->value(Setting::EMail).toString());
	m_ui->password->setText(mixiVoice::decrypt(settings->value(Setting::Password).toByteArray()));
	m_ui->savePassword->setChecked(settings->value(Setting::SavePassword, m_ui->savePassword->isChecked()).toBool());
	m_ui->reloadInterval->setValue(settings->value(Setting::ReloadInterval, m_ui->reloadInterval->value()).toInt());
	m_ui->alwaysOnTop->setChecked(settings->value(Setting::AlwaysOnTop, m_ui->alwaysOnTop->isChecked()).toBool());
	m_ui->notificationShowTime->setValue(settings->value(Setting::NotificationShowTime, m_ui->notificationShowTime->value()).toInt());

	m_ui->enableSound->setChecked(settings->value(Setting::NotificationSoundEnabled, m_ui->enableSound->isChecked()).toBool());
	m_ui->soundPath->setText(settings->value(Setting::NotificationSoundPath, m_ui->soundPath->text()).toString());

	m_ui->maxVoiceCount->setValue(settings->value(Setting::MaxVoiceCount, m_ui->maxVoiceCount->value()).toInt());
	m_ui->voiceFormat->setPlainText(settings->value(Setting::VoiceFormat, m_ui->voiceFormat->toPlainText()).toString());
	m_ui->dateTimeFormat->setText(settings->value(Setting::DateTimeFormat, m_ui->dateTimeFormat->text()).toString());
	m_ui->textColor->setCurrentIndex(m_ui->textColor->findText(settings->value(Setting::WindowTextColor, "black").toString()));
	m_ui->backgroundColor->setCurrentIndex(m_ui->textColor->findText(settings->value(Setting::WindowBackgroundColor, "lightgray").toString()));

	m_ui->clearImageCacheWhenQuit->setChecked(settings->value(Setting::ClearImageCacheWhenQuit, m_ui->clearImageCacheWhenQuit->isChecked()).toBool());

	m_ui->hiddenUserList->addItems(settings->value(Setting::HiddenUsers).toStringList());

	m_ui->voicesStartMarker->setText(settings->value(Setting::VoicesStartMarker, m_ui->voicesStartMarker->text()).toString());
	m_ui->voicesEndMarker->setText(settings->value(Setting::VoicesEndMarker, m_ui->voicesEndMarker->text()).toString());
	m_ui->voiceRegExp->setPlainText(settings->value(Setting::VoiceRegExp, m_ui->voiceRegExp->toPlainText()).toString());
	m_ui->indexOfContent->setValue(settings->value(Setting::RegExpIndexOfContent, m_ui->indexOfContent->value()).toInt());
	m_ui->indexOfDate->setValue(settings->value(Setting::RegExpIndexOfDate, m_ui->indexOfDate->value()).toInt());
	m_ui->indexOfDeletable->setValue(settings->value(Setting::RegExpIndexOfDeletable, m_ui->indexOfDeletable->value()).toInt());
	m_ui->indexOfID->setValue(settings->value(Setting::RegExpIndexOfID, m_ui->indexOfID->value()).toInt());
	m_ui->indexOfImage->setValue(settings->value(Setting::RegExpIndexOfImage, m_ui->indexOfImage->value()).toInt());
	m_ui->indexOfName->setValue(settings->value(Setting::RegExpIndexOfName, m_ui->indexOfName->value()).toInt());


#ifdef Q_OS_MAC
	m_ui->startup->setDisabled(true);
#endif
	checkStartupState();
}

SettingDialog::~SettingDialog()
{
	delete m_ui;
}

void SettingDialog::accept()
{
	settings->setValue(Setting::Version, qApp->applicationVersion());
	settings->setValue(Setting::EMail, m_ui->email->text());
	settings->setValue(Setting::Password, mixiVoice::encrypt(m_ui->password->text().toUtf8()));
	settings->setValue(Setting::SavePassword, m_ui->savePassword->isChecked());
	settings->setValue(Setting::ReloadInterval, m_ui->reloadInterval->value());
	settings->setValue(Setting::AlwaysOnTop, m_ui->alwaysOnTop->isChecked());
	settings->setValue(Setting::NotificationShowTime, m_ui->notificationShowTime->value());
	settings->setValue(Setting::NotificationSoundEnabled, m_ui->enableSound->isChecked());
	settings->setValue(Setting::NotificationSoundPath, m_ui->soundPath->text());
	settings->setValue(Setting::VoiceFormat, m_ui->voiceFormat->toPlainText());
	settings->setValue(Setting::DateTimeFormat, m_ui->dateTimeFormat->text());
	settings->setValue(Setting::MaxVoiceCount, m_ui->maxVoiceCount->value());
	settings->setValue(Setting::WindowTextColor, m_ui->textColor->currentText());
	settings->setValue(Setting::WindowBackgroundColor, m_ui->backgroundColor->currentText());
	settings->setValue(Setting::ClearImageCacheWhenQuit, m_ui->clearImageCacheWhenQuit->isChecked());
	settings->setValue(Setting::FilterEnabled, m_ui->enableFilter->isChecked());

	settings->setValue(Setting::VoicesStartMarker, m_ui->voicesStartMarker->text());
	settings->setValue(Setting::VoicesEndMarker, m_ui->voicesEndMarker->text());
	settings->setValue(Setting::VoiceRegExp, m_ui->voiceRegExp->toPlainText());
	settings->setValue(Setting::RegExpIndexOfContent, m_ui->indexOfContent->value());
	settings->setValue(Setting::RegExpIndexOfDate, m_ui->indexOfDate->value());
	settings->setValue(Setting::RegExpIndexOfDeletable, m_ui->indexOfDeletable->value());
	settings->setValue(Setting::RegExpIndexOfID, m_ui->indexOfID->value());
	settings->setValue(Setting::RegExpIndexOfImage, m_ui->indexOfImage->value());
	settings->setValue(Setting::RegExpIndexOfName, m_ui->indexOfName->value());

	QStringList hiddenUsers;
	for (int i = 0; i != m_ui->hiddenUserList->count(); ++i)
		hiddenUsers.append(m_ui->hiddenUserList->item(i)->text());
	settings->setValue(Setting::HiddenUsers, hiddenUsers);

	saveFilters();

	QDialog::accept();
}

void SettingDialog::applyColors()
{
	m_ui->sample->setText(QString("<p style=\"color:%1; background-color:%2;\">sample text</p>").arg(m_ui->textColor->currentText()).arg(m_ui->backgroundColor->currentText()));
}

void SettingDialog::addHiddenUser()
{
	const QString id = m_ui->hiddenUserID->text();
	if (m_ui->hiddenUserList->findItems(id, Qt::MatchExactly).count() == 0)
		m_ui->hiddenUserList->addItem(id);
}

void SettingDialog::removeHiddenUser()
{
	delete m_ui->hiddenUserList->takeItem(m_ui->hiddenUserList->currentRow());
}

void SettingDialog::clearImageCache()
{
	mixiVoice::clearImageCache();
	QMessageBox::information(this, tr("Cache Cleared"), tr("All image cache has been deleted."));
}

void SettingDialog::selectFilterItem(QTreeWidgetItem *item, QTreeWidgetItem *prev)
{
	if (m_ui->filterList->currentItem() == NULL)	return;
	m_ui->filterKey->setText(item->text(ColumnKey));
	m_ui->filterValue->setText(item->text(ColumnValue));
}

void SettingDialog::addFilter()
{
	const QString key = m_ui->filterKey->text();
	if (key.isEmpty())	return;
	if (filterContainsKey(key))	return;
	m_ui->filterList->setCurrentItem(new QTreeWidgetItem(m_ui->filterList, QStringList() << key << m_ui->filterValue->text()));
}

void SettingDialog::deleteFilter()
{
	delete m_ui->filterList->takeTopLevelItem(m_ui->filterList->indexOfTopLevelItem(m_ui->filterList->currentItem()));
}

void SettingDialog::changeFilter()
{
	const QString key = m_ui->filterKey->text();
	const QString value = m_ui->filterValue->text();
	deleteFilter();
	m_ui->filterKey->setText(key);
	m_ui->filterValue->setText(value);
	addFilter();
}

bool SettingDialog::filterContainsKey(const QString &key)
{
	return 0 < m_ui->filterList->findItems(key, Qt::MatchExactly, ColumnKey).count();
}

void SettingDialog::resetFilter()
{
	m_ui->filterList->clear();
	QMap<QString, QString> m;
/*
	m.insert("&nbsp;", "");
	m.insert("&iexcl;", "");
	m.insert("&cent;", "");
	m.insert("&pound;", "");
	m.insert("&curren;", "");
	m.insert("&yen;", "");
	m.insert("&brvbar;", "");
	m.insert("&sect;", "");
	m.insert("&uml;", "");
	m.insert("&copy;", "");
	m.insert("&ordf;", "");
	m.insert("&laquo;", "");
	m.insert("&not;", "");
	m.insert("&shy;", "");
	m.insert("&reg;", "");
	m.insert("&macr;", "");
	m.insert("&deg;", "");
	m.insert("&plusmn;", "");
	m.insert("&sup2;", "");
	m.insert("&sup3;", "");
	m.insert("&acute;", "");
	m.insert("&micro;", "");
	m.insert("&para;", "");
	m.insert("&middot;", "");
	m.insert("&cedil;", "");
	m.insert("&sup1;", "");
	m.insert("&ordm;", "");
	m.insert("&raquo;", "");
	m.insert("&frac14;", "");
	m.insert("&frac12;", "");
	m.insert("&frac34;", "");
	m.insert("&iquest;", "");
	m.insert("&Agrave;", "");
	m.insert("&Aacute;", "");
	m.insert("&Acirc;", "");
	m.insert("&Atilde;", "");
	m.insert("&Auml;", "");
	m.insert("&Aring;", "");
	m.insert("&AElig;", "");
	m.insert("&Ccedil;", "");
	m.insert("&Egrave;", "");
	m.insert("&Eacute;", "");
	m.insert("&Ecirc;", "");
	m.insert("&Euml;", "");
	m.insert("&Igrave;", "");
	m.insert("&Iacute;", "");
	m.insert("&Icirc;", "");
	m.insert("&Iuml;", "");
	m.insert("&ETH;", "");
	m.insert("&Ntilde;", "");
	m.insert("&Ograve;", "");
	m.insert("&Oacute;", "");
	m.insert("&Ocirc;", "");
	m.insert("&Otilde;", "");
	m.insert("&Ouml;", "");
	m.insert("&times;", "");
	m.insert("&Oslash;", "");
	m.insert("&Ugrave;", "");
	m.insert("&Uacute;", "");
	m.insert("&Ucirc;", "");
	m.insert("&Uuml;", "");
	m.insert("&Yacute;", "");
	m.insert("&THORN;", "");
	m.insert("&szlig;", "");
	m.insert("&agrave;", "");
	m.insert("&aacute;", "");
	m.insert("&acirc;", "");
	m.insert("&atilde;", "");
	m.insert("&auml;", "");
	m.insert("&aring;", "");
	m.insert("&aelig;", "");
	m.insert("&ccedil;", "");
	m.insert("&egrave;", "");
	m.insert("&ecirc;", "");
	m.insert("&euml;", "");
	m.insert("&igrave;", "");
	m.insert("&iacute;", "");
	m.insert("&icirc;", "");
	m.insert("&iuml;", "");
	m.insert("&eth;", "");
	m.insert("&ntilde;", "");
	m.insert("&ograve;", "");
	m.insert("&oacute;", "");
	m.insert("&ocirc;", "");
	m.insert("&otilde;", "");
	m.insert("&ouml;", "");
	m.insert("&divide;", "");
	m.insert("&oslash;", "");
	m.insert("&ugrave;", "");
	m.insert("&uacute;", "");
	m.insert("&ucirc;", "");
	m.insert("&uuml;", "");
	m.insert("&yacute;", "");
	m.insert("&thorn;", "");
	m.insert("&yuml;", "");
*/
}

void SettingDialog::saveFilters()
{
	QMap<QString, QVariant> map;
	for (QTreeWidgetItemIterator it(m_ui->filterList); *it; ++it)
		map[(*it)->text(ColumnKey)] = QVariant((*it)->text(ColumnValue));
	settings->setValue(Setting::Filters, QVariant(map));
}

void SettingDialog::loadFilters()
{
	if (settings->contains(Setting::Filters) == false)
	{
		resetFilter();
		return;
	}

	m_ui->filterList->clear();
	QMap<QString, QVariant> map = settings->value(Setting::Filters).toMap();
	for (QMap<QString, QVariant>::const_iterator it = map.constBegin(); it != map.constEnd(); ++it)
		new QTreeWidgetItem(m_ui->filterList, QStringList() << it.key() << it.value().toString());
}

void SettingDialog::chooseSound()
{
#if defined Q_OS_WIN32
	const QString defaultPath = "C:/Windows/Media";
	const QString nameFilter = "*.wav";
#elif defined Q_OS_MAC
	const QString defaultPath = "/System/Library/Sounds";
	const QString nameFilter = "";
#else
	const QString defaultPath = "";
	const QString nameFilter = "";
#endif
	QString path = QFileDialog::getOpenFileName(this, tr("Choose Notification Sound File"), defaultPath, nameFilter);
	if (path.isNull())	return;
	m_ui->soundPath->setText(path);
}

void SettingDialog::checkStartupState()
{
#ifdef Q_OS_WIN32
	m_ui->startup->setEnabled(true);

	QSettings userreg("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat);
	m_ui->startup->setChecked(userreg.contains(qApp->applicationName()));
#endif
}

void SettingDialog::toggleStartupCurrentUser(bool checked)
{
	QSettings userreg("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat);
	if (checked)	userreg.setValue(qApp->applicationName(), QString("\"%1\"").arg(QCoreApplication::applicationFilePath()).replace('/', '\\'));
	else	userreg.remove(qApp->applicationName());
	checkStartupState();
}
